/*
 * Copyright 2011 Jin Kwon <jinahya at gmail.com>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.googlecode.flac4j.format.metadata;


import com.googlecode.jinahya.io.BitInput;
import com.googlecode.jinahya.io.BitOutput;
import com.googlecode.jinahya.util.BitAccessible;

import java.io.IOException;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;


/**
 *
 * @author Jin Kwon <jinahya at gmail.com>
 */
@XmlType(propOrder = {"sampleNumber", "byteOffset", "sampleCount"})
public class Seekpoint implements BitAccessible, Comparable<Seekpoint> {


    /** GENERATED. */
    private static final long serialVersionUID = -2447363658308324831L;


    /** fixed length in bytes. */
    protected static final int LENGTH_IN_BYTES = 18;


    /** sample number for placeholder points. */
    public static final long PLACEHOLDER = 0xFFFFFFFFFFFFFFFFL;


    @Override
    public void read(final BitInput input) throws IOException {

        setSampleNumber(input.readLong(64));
        setByteOffset(input.readLong(64));
        setSampleCount(input.readUnsignedInt(16));
    }


    @Override
    public void write(final BitOutput output) throws IOException {

        output.writeLong(64, getSampleNumber());
        output.writeLong(64, getByteOffset());
        output.writeUnsignedInt(16, getSampleCount());
    }


    @Override
    public int compareTo(final Seekpoint o) {

        if (isPlaceholder()) {
            return 1;
        }

        if (o.isPlaceholder()) {
            return -1;
        }

        return Long.valueOf(sampleNumber).compareTo(o.sampleNumber);
    }


    // ------------------------------------------------------------ sampleOffset
    public long getSampleNumber() {
        return sampleNumber;
    }


    public void setSampleNumber(final long sampleNumber) {
        this.sampleNumber = sampleNumber;
    }


    public boolean isPlaceholder() {
        return getSampleNumber() == PLACEHOLDER;
    }

    // -------------------------------------------------------------- byteOffset

    public long getByteOffset() {
        return byteOffset;
    }


    public void setByteOffset(final long byteOffset) {
        this.byteOffset = byteOffset;
    }


    // ------------------------------------------------------------- sampleCount
    public int getSampleCount() {
        return sampleCount;
    }


    public void setSampleCount(final int sampleCount) {

        if (sampleNumber != PLACEHOLDER && sampleCount < 0) {
            throw new IllegalArgumentException(
                "sampleLength(" + sampleCount + ") < 0");
        }

        this.sampleCount = sampleCount;
    }


    /** sample number. */
    @XmlElement(required = true)
    private long sampleNumber;


    /** byte offset. */
    @XmlElement(required = true)
    private long byteOffset;


    /** sample count. */
    @XmlElement(required = true)
    private int sampleCount;


}

